﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Fcdbas.Core.WCF.TransFile.Service.Common
{

    ///<summary>
    ///作者:   谢海波
    ///时间:   2011-09-15
    ///描述:   文件操作
    ///<summary>
    public class FileManager
    {
        #region CopyFileToTempDir
        /// <summary>
        /// 将文件复制到临时目录
        /// </summary>
        /// <param name="srcFile">源文件</param>
        /// <returns>临时文件名称</returns>
        public static string CopyFileToTempDir(string srcFile)
        {
            return CopyFileToTempDir(srcFile, true);
        }

        /// <summary>
        /// 将文件复制到临时目录
        /// </summary>
        /// <param name="srcFile">源文件</param>
        /// <param name="overWrite">是否覆盖原文件</param>
        /// <returns>临时文件名称</returns>
        public static string CopyFileToTempDir(string srcFile, bool overWrite)
        {
            if (!System.IO.File.Exists(srcFile)) return "";
            string tempFile = GetTempFileName(System.IO.Path.GetExtension(srcFile));
            //			try {
            File.Copy(srcFile, tempFile, overWrite);
            //			}
            //			catch {
            //				System.Windows.Forms.MessageBox.Show("在将文件复制到临时目录时遇到错误！");
            //			}
            return tempFile;
        }

        /// <summary>
        /// 提供一个扩展名，返回一个可用的临时文件路径
        /// </summary>
        /// <param name="extension">扩展名,要加.</param>
        /// <returns>路径</returns>
        public static string GetTempFileName(string extension)
        {
            string tempdir = System.IO.Path.GetTempPath();
            string tempFile = "";
            Directory.CreateDirectory(tempdir);
            do
            {
                string tmp = System.Guid.NewGuid().ToString() + extension;
                tempFile = tempdir + tmp;
            }
            while (File.Exists(tempFile));
            return tempFile;
        }

        /// <summary>
        /// 删除文件，如果异常不报错
        /// </summary>
        /// <param name="tempFile"></param>
        public static void DeleteTempFile(string tempFile)
        {
            try
            {
                System.IO.File.Delete(tempFile);
            }
            catch
            {
            }
        }

        #endregion

        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static byte[] Open(string fileName)
        {
            ///为了防止文件被其它程序打开而无法访问，所以先将它复制到临时目录进行处理。

            if (!File.Exists(fileName)) return null;
            string tmp = GetTempFileName(".tmp");
            System.IO.File.Copy(fileName, tmp);
            using (FileStream fs = File.Open(tmp, FileMode.Open, FileAccess.Read))
            {
                byte[] tmpBuf = new byte[fs.Length];
                fs.Read(tmpBuf, 0, tmpBuf.Length);
                fs.Close();
                try
                {
                    System.IO.File.Delete(tmp);
                }
                catch
                {
                }
                return tmpBuf;//return Microsoft.Common.ZipClass.SaveObjectZip(tmpBuf);
            }
        }

        /// <summary>
        /// 获取文件字节
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static byte[] GetFileBytes(string fileName)
        {
            return GetFileBytes(string.Empty, fileName);
        }

        /// <summary>
        /// 获取文件字节(适合服务器端调用)
        /// </summary>
        /// <param name="webSitePhysicsPath"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static byte[] GetFileBytes(string webSitePhysicsPath, string fileName)
        {
            string str = fileName;
            if (!string.IsNullOrEmpty(webSitePhysicsPath))
                str = System.IO.Path.Combine(webSitePhysicsPath, fileName);

            if (!File.Exists(str)) return null;
            using (FileStream fs = File.Open(str, FileMode.Open, FileAccess.Read))
            {
                byte[] tmpBuf = new byte[fs.Length];
                fs.Read(tmpBuf, 0, tmpBuf.Length);
                fs.Close();

                return tmpBuf;//return Microsoft.Common.ZipClass.SaveObjectZip(tmpBuf);
            }

            //         int offset=0;

            //int remaining = data.Length;

            //   // 只要有剩余的字节就不停的读


            //while (remaining > 0){

            //    int read = stream.Read(data, offset, remaining);

            //    if (read <= 0)

            //        throw new EndOfStreamException("文件读取到"+read.ToString()+"失败！");

            //          // 减少剩余的字节数

            //    remaining -= read;

            //          // 增加偏移量


            //    offset += read;


        }

        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="ofileData">byte[]</param>
        /// <param name="fileName">保存路径</param>
        /// <returns></returns>
        public static bool SaveFile(object ofileData, string fileName)
        {
            if (ofileData == null)
            {
                return false;
            }

            byte[] fileData = (byte[])ofileData;

            if (fileData == null) return false;
            string filePath = Path.GetDirectoryName(fileName);

            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }

            if (System.IO.File.Exists(fileName))
            {
                try
                {
                    System.IO.File.Delete(fileName);
                }
                catch
                {
                    return true;
                }
            }

            using (FileStream fs = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write))
            {
                fs.Write(fileData, 0, fileData.Length);
                fs.Flush();
                fs.Close();
                return true;
            }
        }

        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="ofileData">byte[]</param>
        /// <param name="fileName">保存路径</param>
        /// <returns></returns>
        public static bool SaveFile(object ofileData, string fileName, out bool createDirectory)
        {
            createDirectory = false;
            if (ofileData == null)
            {
                return false;
            }

            byte[] fileData = (byte[])ofileData;

            if (fileData == null) return false;
            string filePath = Path.GetDirectoryName(fileName);

            if (!Directory.Exists(filePath))
            {
                createDirectory = true;
                Directory.CreateDirectory(filePath);
            }

            if (System.IO.File.Exists(fileName))
            {
                try
                {
                    if (System.IO.File.GetAttributes(fileName) != FileAttributes.Normal)
                    {
                        System.IO.File.SetAttributes(fileName, FileAttributes.Normal);
                    }
                    System.IO.File.Delete(fileName);
                }
                catch (Exception ee)
                {
                    throw ee;
                    return false;
                }
            }

            using (FileStream fs = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write))
            {
                fs.Write(fileData, 0, fileData.Length);
                fs.Flush();
                fs.Close();
                return true;
            }
        }

        #region 调用API操作文件
        private const int FO_DELETE = 0x3;
        private const int FO_MOVE = 0x1;
        private const int FO_COPY = 0x2;
        private const ushort FOF_NOCONFIRMATION = 0x10;
        private const ushort FOF_ALLOWUNDO = 0x40;

        /// <summary>
        /// 调用API删除文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static int Delete(string path)
        {
            if (!System.IO.File.Exists(path)) return -1;

            try
            {
                FileInfo info = new FileInfo(path);
                info.IsReadOnly = false;

                info.Delete();
            }
            catch { return -1; }
            return 0;
            //API.SHFILEOPSTRUCT pm = new API.SHFILEOPSTRUCT();
            //pm.wFunc = FO_DELETE;
            //pm.pFrom = path + '\0';
            //pm.fFlags = FOF_ALLOWUNDO;
            //pm.pTo = null;
            //return API.SHFileOperation(pm);
        }

        /// <summary>
        /// 调用API提示用户移动文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static int Move(string fromPath, string toPath)
        {
            //if (!System.IO.File.Exists(fromPath)) return -1;
            //System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(toPath));
            //API.SHFILEOPSTRUCT pm = new API.SHFILEOPSTRUCT();
            //pm.wFunc = FO_MOVE;
            //pm.pFrom = fromPath + '\0';
            //pm.pTo = toPath + '\0';
            //return API.SHFileOperation(pm);
            if (!File.Exists(fromPath))
                return -1;
            string folder = Path.GetDirectoryName(toPath);
            if (!Directory.Exists(folder))
                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(toPath));

            File.Move(fromPath, toPath);

            return 1;
        }

        /// <summary>
        /// 调用API提示用户复制文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static int Copy(string fromPath, string toPath)
        {
            //if (!System.IO.File.Exists(fromPath)) return -1;
            //System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(toPath));
            //API.SHFILEOPSTRUCT pm = new API.SHFILEOPSTRUCT();
            //pm.wFunc = FO_COPY;
            //pm.pFrom = fromPath + '\0';
            //pm.pTo = toPath + '\0';
            //return API.SHFileOperation(pm);

            if (!File.Exists(fromPath))
                return -1;
            string folder = Path.GetDirectoryName(toPath);
            if (!Directory.Exists(folder))
                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(toPath));

            File.Copy(fromPath, toPath);

            return 1;
        }

        public static int Copy(string fromPath, string toPath, bool overwrite)
        {
            if (!File.Exists(fromPath))
                return -1;
            string folder = Path.GetDirectoryName(toPath);
            if (!Directory.Exists(folder))
                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(toPath));

            File.Copy(fromPath, toPath, overwrite);

            return 1;
        }

        #endregion

        /// <summary>
        /// 判断文件地址在当前计算机上是否是合法地址
        /// </summary>
        /// <param name="path">地址</param>
        /// <param name="deleteFile">是否删除因为判断而生成的临时文件</param>
        /// <returns></returns>
        public static bool IsUseablePath(string path, bool deleteFile)
        {
            if (System.IO.File.Exists(path)) return true;

            System.IO.Stream s = null;
            try
            {
                s = System.IO.File.Create(path);
            }
            catch
            {
                return false;
            }
            finally
            {
                if (s != null) s.Close();
            }
            if (deleteFile) System.IO.File.Delete(path);
            return true;
        }

        /// <summary>
        /// 判断文件地址在当前计算机上是否是合法地址
        /// </summary>
        /// <param name="path">地址</param>
        /// <returns></returns>
        public static bool IsUseablePath(string path)
        {
            return IsUseablePath(path, false);
        }

        /// <summary>
        /// 验证文件夹是否为今天的文件夹,删除非今天的文件夹
        /// </summary>
        /// <param name="folder">文件夹根路径</param>
        public static bool DeleteNotTodayFolders(string folder)
        {
            if (string.IsNullOrEmpty(folder))
                return false;

            try
            {
                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                    return true;
                }

                bool foundToday = false;
                string todayFolderName = DateTime.Now.ToString("yyyy-MM-dd");

                string[] folderList = Directory.GetDirectories(folder);
                if (folderList != null && folderList.Length > 0)
                {
                    foreach (string folderPath in folderList)
                    {
                        DirectoryInfo info = new DirectoryInfo(folderPath);
                        if (info != null)
                        {
                            if (info.Name != todayFolderName)
                            {
                                DeleteFolder(info);
                                //try
                                //{
                                //    foreach (FileInfo fileInfo in info.GetFiles())
                                //    {
                                //        fileInfo.IsReadOnly = false;
                                //        fileInfo.Delete();
                                //    }

                                //    info.Delete();
                                //}
                                //catch (Exception ex)
                                //{
                                //    LogHelper.WriteError("删除非今天的文件夹失败", ex);
                                //}
                            }
                            else
                            {
                                foundToday = true;
                            }
                        }
                    }
                }

                if (!foundToday)
                {
                    Directory.CreateDirectory(Path.Combine(folder, todayFolderName));
                }

                return true;
            }
            catch (Exception ex)
            {
                //LogHelper.WriteError("验证截图保存路径失败", ex);
            }
            return false;
        }

        /// <summary>
        /// 删除文件夹
        /// </summary>
        /// <param name="folder">文件夹</param>
        /// <returns></returns>
        public static bool DeleteFolder(string folder)
        {
            if (!Directory.Exists(folder))
                return true;
            return DeleteFolder(new DirectoryInfo(folder));
        }

        public static bool DeleteFolder(DirectoryInfo folder)
        {
            if (folder == null)
                return true;

            try
            {
                foreach (FileInfo fileInfo in folder.GetFiles())
                {
                    fileInfo.IsReadOnly = false;
                    fileInfo.Delete();
                }
                foreach (DirectoryInfo info in folder.GetDirectories())
                {
                    DeleteFolder(info);
                }

                folder.Delete();
                return true;
            }
            catch (Exception ex)
            {
                //LogHelper.WriteError("删除文件夹失败", ex);
            }
            return false;
        }


        public static List<string> GetFileNegativePathList(string dir, string folder)
        {
            List<string> files = new List<string>();
            if (Directory.Exists(folder))
            {
                string[] filePaths = Directory.GetFiles(folder);
                if (filePaths != null && filePaths.Length > 0)
                {
                    foreach (string filePath in filePaths)
                    {
                        files.Add(filePath.Replace(dir + "\\", string.Empty));
                    }
                }

                string[] folders = Directory.GetDirectories(folder);
                if (folders != null && folders.Length > 0)
                {
                    foreach (string folderItem in folders)
                    {
                        files.AddRange(GetFileNegativePathList(dir, folderItem));
                    }
                }
            }
            return files;
        }

        public static List<string> GetAllFiles(string folder)
        {
            List<string> files = new List<string>();
            if (Directory.Exists(folder))
            {
                string[] filePaths = Directory.GetFiles(folder);
                if (filePaths != null && filePaths.Length > 0)
                {
                    //foreach (string filePath in filePaths)
                    //{
                    //    files.Add(filePath);
                    //}

                    files.AddRange(filePaths);
                }

                string[] folders = Directory.GetDirectories(folder);
                if (folders != null && folders.Length > 0)
                {
                    foreach (string folderItem in folders)
                    {
                        files.AddRange(GetAllFiles(folderItem));
                    }
                }
            }
            return files;
        }


        public static string GetDirPath(string path)
        {
            int index = path.TrimEnd('\\').LastIndexOf('\\');
            if (index > 0)
            {
                path = path.Remove(index);
            }
            return path;
        }

        private const string _CustomSuffix = ".wbd";
        /// <summary>
        /// 添加自定义后缀
        /// </summary>
        /// <param name="path">路径</param>
        /// <returns>返回包含自定义后缀的路径</returns>
        public static string EndsWithCustomSuffix(string path)
        {
            if (string.IsNullOrEmpty(path))
                return path;

            if (path.LastIndexOf(_CustomSuffix) > -1)
            {
                return path;
            }
            return path += _CustomSuffix;

        }

        /// <summary>
        /// 取出自定义后缀
        /// </summary>
        /// <param name="path">路径</param>
        /// <returns>返回不包含自定后缀的路径</returns>
        public static string TrimEndCustomSuffix(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return path;
            }
            if (path.IndexOf(_CustomSuffix) < 0)
            {
                return path;
            }
            return path.Substring(0, path.LastIndexOf(_CustomSuffix));
        }

        public static long GetDirectoryLength(string dirPath)
        {
            //判断给定的路径是否存在,如果不存在则退出
            if (!Directory.Exists(dirPath))
            {
                return 0;
            }
            long len = 0;

            //定义一个DirectoryInfo对象
            DirectoryInfo di = new DirectoryInfo(dirPath);

            //通过GetFiles方法,获取di目录中的所有文件的大小
            foreach (FileInfo fi in di.GetFiles())
            {
                len += fi.Length;
            }

            //获取di中所有的文件夹,并存到一个新的对象数组中,以进行递归
            DirectoryInfo[] dis = di.GetDirectories();
            if (dis.Length > 0)
            {
                for (int i = 0; i < dis.Length; i++)
                {
                    len += GetDirectoryLength(dis[i].FullName);
                }
            }
            return len;
        }

        public static long GetFileSize(string filePath)
        {
            long temp = 0;

            //判断当前路径所指向的是否为文件
            if (File.Exists(filePath) == false)
            {
                string[] str1 = Directory.GetFileSystemEntries(filePath);
                foreach (string s1 in str1)
                {
                    temp += GetFileSize(s1);
                }
            }
            else
            {

                //定义一个FileInfo对象,使之与filePath所指向的文件向关联,

                //以获取其大小
                FileInfo fileInfo = new FileInfo(filePath);
                return fileInfo.Length;
            }
            return temp;
        }


        public static long GetFileSize(string filePath, ref int folderCount, ref int fileCount)
        {
            long temp = 0;
            //folderCount = 0;
            //fileCount = 0;
            //判断当前路径所指向的是否为文件
            if (File.Exists(filePath) == false)
            {
                folderCount++;
                string[] str1 = Directory.GetFileSystemEntries(filePath);
                foreach (string s1 in str1)
                {
                    temp += GetFileSize(s1, ref  folderCount, ref  fileCount);
                }
            }
            else
            {

                //定义一个FileInfo对象,使之与filePath所指向的文件向关联,
                fileCount++;
                //以获取其大小
                FileInfo fileInfo = new FileInfo(filePath);
                return fileInfo.Length;
            }
            return temp;
        }



        public static long GetFileSize(string[] filePaths, ref int folderCount, ref int fileCount)
        {

            long length = 0;
            int folderCountTmp = 0;
            int fileCountTmp = 0;
            foreach (string file in filePaths)
            {
                length += GetFileSize(file, ref  folderCountTmp, ref  fileCountTmp);
                folderCount += folderCountTmp;
                fileCount += fileCountTmp;
            }


            return length;
        }

    }
}
